﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using cs = Constant;

struct Situation
{   //当前位置的形式，打分根据这个来打
    public int win5;//5连珠
    public int alive4;//活4
    public int die4;//死4
    public int lowdie4;//死4低级版本
    public int alive3;//活3
    public int tiao3;//跳3
    public int die3;//死3
    public int alive2;//活2
    public int lowalive2;//低级活2
    public int die2;//死2
    public int nothreat;//没有威胁
};

public class ZllSecond{

    public Point Excute(CrossVal[,] map, CrossVal aiValue)
    {
        //判断是否第一次下棋
        bool isFirst = true;
        foreach(var v in map)
        {
            if (v != CrossVal.nil)
            {
                isFirst = false;
                break;
            }
        }
        if (isFirst)
            return new Point(7, 7);

        //打分
        int[,] myscore = new int[cs.CrossCount, cs.CrossCount];//我的分数
        int[,] hisscore = new int[cs.CrossCount, cs.CrossCount];//对手的分数
        for (int i = 0; i< cs.CrossCount; i++)
		    for (int j = 0; j< cs.CrossCount; j++) {
                Point position = new Point(i, j);

			    //我的分数
			    int score = GetScore(map, position, aiValue);//返回当前形势分数
                myscore[i,j] = score;

                //对手分数
                CrossVal playerValue = Util.UnCrossVal(aiValue);
                score = GetScore(map, position, playerValue);//返回当前形势分数
                hisscore[i,j] = score;
		    }

	    //根据分数，给出位置
        return maxScore(myscore, hisscore);
    }

    int GetScore(CrossVal[,] map, Point pt, CrossVal value)
    {
        if (Util.GetMapValue(map, pt) != CrossVal.nil)
            return 0;

        Situation situation = new Situation();//记录当前形势变量
        Point[] arrPoint = new Point[4] { new Point(1, 0), new Point(1, 1), new Point(0, 1), new Point(1, -1) };
        for(int i = 0; i<4; i++)
            {
                int type = GetType(map, pt, value, arrPoint[i]);
                switch (type)
                {//根据类型对situation设置
                    case cs.WIN5:
                        situation.win5++;
                        break;
                    case cs.ALIVE4:
                        situation.alive4++;
                        break;
                    case cs.DIE4:
                        situation.die4++;
                        break;
                    case cs.LOWDIE4:
                        situation.lowdie4++;
                        break;
                    case cs.ALIVE3:
                        situation.alive3++;
                        break;
                    case cs.TIAO3:
                        situation.tiao3++;
                        break;
                    case cs.DIE3:
                        situation.die3++;
                        break;
                    case cs.ALIVE2:
                        situation.alive2++;
                        break;
                    case cs.LOWALIVE2:
                        situation.lowalive2++;
                        break;
                    case cs.DIE2:
                        situation.die2++;
                        break;
                    case cs.NOTHREAT:
                        situation.nothreat++;
                        break;
                    default:
                        //差错控制
                        break;
                }
            }

        return giveScore(situation);//根据形势得出分数
    }


    int GetType(CrossVal[,] map, Point pt, CrossVal value, Point direction)
    {
        CrossVal[] arrChess = new CrossVal[9];

        for (int i = -4; i <= 4; i++)
        {
            CrossVal val = Util.GetMapValue(map, pt + i * direction);
            arrChess[i + 4] = val;
        }

        return judgeType(arrChess, value);
    }

    int judgeType(CrossVal[] chess, CrossVal mycolor)
    {
        CrossVal hiscolor = Util.UnCrossVal(mycolor);

        int left = 0, right = 0;//开始和中心线断开的位置
        CrossVal colorleft = CrossVal.out_of_range, colorright = CrossVal.out_of_range;//开始和中心线断开的颜色，NOTHING或者hiscolor
        int count = 1;//中心线有多少个，初始化

        for (int i = 1; i <= 4; i++)
        {
            if (chess[4 - i] == mycolor)
                count++;//同色
            else
            {
                left = 4 - i;//保存断开位置
                colorleft = chess[4 - i];//保存断开颜色
                break;
            }
        }
        for (int i = 1; i <= 4; i++)
        {
            if (chess[4 + i] == mycolor)
                count++;//同色
            else
            {
                right = 4 + i;//保存断开位置
                colorright = chess[4 + i];//保存断开颜色
                break;
            }
        }

        if (count >= 5)//中心线5连
            return cs.WIN5;//5连珠

        if (count == 4)//中心线4连
        {
            if (colorleft == CrossVal.nil && colorright == CrossVal.nil)//两边断开位置均空
                return cs.ALIVE4;//活四
            else if (colorleft != CrossVal.nil && colorright != CrossVal.nil)//两边断开位置均非空
                return cs.NOTHREAT;//没有威胁
            else if (colorleft == CrossVal.nil || colorright == CrossVal.nil)//两边断开位置只有一个空
                return cs.DIE4;//死四
        }

        if (count == 3)
        {   //中心线3连
            CrossVal colorleft1 = chess[left - 1];
            CrossVal colorright1 = chess[right + 1];

            if (colorleft == CrossVal.nil && colorright == CrossVal.nil)//两边断开位置均空
            {

                if (colorleft1 != CrossVal.nil && colorright1 != CrossVal.nil)//两边都不可下
                    return cs.DIE3;
                else if (colorleft1 == CrossVal.nil || colorright1 == CrossVal.nil)//只要一个为自己的棋子
                    return cs.LOWDIE4;
                else if (colorleft1 == CrossVal.nil || colorright1 == CrossVal.nil)//只要有一个空
                    return cs.ALIVE3;

            }
            else if (colorleft != CrossVal.nil && colorright != CrossVal.nil)//两边断开位置均非空
            {
                return cs.NOTHREAT;//没有威胁
            }
            else if (colorleft == CrossVal.nil || colorright == CrossVal.nil)//两边断开位置只有一个空
            {

                if (colorleft != CrossVal.nil)
                {   //左边被堵住
                    if (colorright1 != CrossVal.nil)//右边也被堵住
                        return cs.NOTHREAT;
                    if (colorright1 == CrossVal.nil)//右边均空
                        return cs.DIE3;
                    if (colorright1 == mycolor)
                        return cs.LOWDIE4;
                }
                if (colorright != CrossVal.nil)
                {   //右边被对方堵住
                    if (colorleft1 != CrossVal.nil)//左边也被对方堵住
                        return cs.NOTHREAT;
                    if (colorleft1 == CrossVal.nil)//左边均空
                        return cs.DIE3;
                    if (colorleft1 == mycolor)//左边还有自己的棋子
                        return cs.LOWDIE4;
                }
            }
        }

        if (count == 2)
        {   
            //中心线2连
            CrossVal colorleft1 = chess[left - 1];
            CrossVal colorright1 = chess[right + 1];
            CrossVal colorleft2 = chess[left - 2];
            CrossVal colorright2 = chess[right + 2];

            //两边断开位置均空
            if (colorleft == CrossVal.nil && colorright == CrossVal.nil)
            {
                if ((colorright1 == CrossVal.nil && colorright2 == mycolor) ||
                    (colorleft1 == CrossVal.nil && colorleft2 == mycolor))
                    return cs.DIE3;//死3
                else if (colorleft1 == CrossVal.nil && colorright1 == CrossVal.nil)
                    return cs.ALIVE2;//活2

                if ((colorright1 == mycolor && colorright2 != CrossVal.nil) ||
                    (colorleft1 == mycolor && colorleft2 != CrossVal.nil))
                    return cs.DIE3;//死3

                if ((colorright1 == mycolor && colorright2 == mycolor) ||
                    (colorleft1 == mycolor && colorleft2 == mycolor))
                    return cs.LOWDIE4;//死4

                if ((colorright1 == mycolor && colorright2 == CrossVal.nil) ||
                    (colorleft1 == mycolor && colorleft2 == CrossVal.nil))
                    return cs.TIAO3;//跳活3
                                 //其他情况在下边返回NOTHREAT
            }
            else if (colorleft != CrossVal.nil && colorright != CrossVal.nil)//两边断开位置均非空
            {
                return cs.NOTHREAT;
            }
            else if (colorleft == CrossVal.nil || colorright == CrossVal.nil)//两边断开位置只有一个空
            {
                if (colorleft != CrossVal.nil)
                {//左边被对方堵住
                    if (colorright1 != CrossVal.nil || colorright2 != CrossVal.nil)
                    {//只要有对方的一个棋子
                        return cs.NOTHREAT;//没有威胁
                    }
                    else if (colorright1 == CrossVal.nil && colorright2 == CrossVal.nil)
                    {//均空
                        return cs.DIE2;//死2
                    }
                    else if (colorright1 == mycolor && colorright2 == mycolor)
                    {//均为自己的棋子
                        return cs.LOWDIE4;//死4
                    }
                    else if (colorright1 == mycolor || colorright2 == mycolor)
                    {//只有一个自己的棋子
                        return cs.DIE3;//死3
                    }
                }
                if (colorright != CrossVal.nil)
                {//右边被对方堵住
                    if (colorleft1 != CrossVal.nil || colorleft2 != CrossVal.nil)
                    {//只要有对方的一个棋子
                        return cs.NOTHREAT;//没有威胁
                    }
                    else if (colorleft1 == CrossVal.nil && colorleft2 == CrossVal.nil)
                    {//均空
                        return cs.DIE2;//死2
                    }
                    else if (colorleft1 == mycolor && colorleft2 == mycolor)
                    {//均为自己的棋子
                        return cs.LOWDIE4;//死4
                    }
                    else if (colorleft1 == mycolor || colorleft2 == mycolor)
                    {//只有一个自己的棋子
                        return cs.DIE3;//死3
                    }
                }
            }
        }

        if (count == 1)
        {//中心线1连
            CrossVal colorleft1 = chess[left - 1];
            CrossVal colorright1 = chess[right + 1];
            CrossVal colorleft2 = chess[left - 2];
            CrossVal colorright2 = chess[right + 2];
            CrossVal colorleft3 = chess[left - 3];
            CrossVal colorright3 = chess[right + 3];

            if (colorleft == CrossVal.nil && colorleft1 == mycolor &&
                colorleft2 == mycolor && colorleft3 == mycolor)
                return cs.LOWDIE4;
            if (colorright == CrossVal.nil && colorright1 == mycolor &&
                colorright2 == mycolor && colorright3 == mycolor)
                return cs.LOWDIE4;

            if (colorleft == CrossVal.nil && colorleft1 == mycolor &&
                colorleft2 == mycolor && colorleft3 == CrossVal.nil && colorright == CrossVal.nil)
                return cs.TIAO3;
            if (colorright == CrossVal.nil && colorright1 == mycolor &&
                colorright2 == mycolor && colorright3 == CrossVal.nil && colorleft == CrossVal.nil)
                return cs.TIAO3;

            if (colorleft == CrossVal.nil && colorleft1 == mycolor &&
                colorleft2 == mycolor && colorleft3 != CrossVal.nil && colorright == CrossVal.nil)
                return cs.DIE3;
            if (colorright == CrossVal.nil && colorright1 == mycolor &&
                colorright2 == mycolor && colorright3 != CrossVal.nil && colorleft == CrossVal.nil)
                return cs.DIE3;

            if (colorleft == CrossVal.nil && colorleft1 == CrossVal.nil &&
                colorleft2 == mycolor && colorleft3 == mycolor)
                return cs.DIE3;
            if (colorright == CrossVal.nil && colorright1 == CrossVal.nil &&
                colorright2 == mycolor && colorright3 == mycolor)
                return cs.DIE3;

            if (colorleft == CrossVal.nil && colorleft1 == mycolor &&
                colorleft2 == CrossVal.nil && colorleft3 == mycolor)
                return cs.DIE3;
            if (colorright == CrossVal.nil && colorright1 == mycolor &&
                colorright2 == CrossVal.nil && colorright3 == mycolor)
                return cs.DIE3;

            if (colorleft == CrossVal.nil && colorleft1 == mycolor &&
                colorleft2 == CrossVal.nil && colorleft3 == CrossVal.nil && colorright == CrossVal.nil)
                return cs.LOWALIVE2;
            if (colorright == CrossVal.nil && colorright1 == mycolor &&
                colorright2 == CrossVal.nil && colorright3 == CrossVal.nil && colorleft == CrossVal.nil)
                return cs.LOWALIVE2;

            if (colorleft == CrossVal.nil && colorleft1 == CrossVal.nil &&
                colorleft2 == mycolor && colorleft3 == CrossVal.nil && colorright == CrossVal.nil)
                return cs.LOWALIVE2;
            if (colorright == CrossVal.nil && colorright1 == CrossVal.nil &&
                colorright2 == mycolor && colorright3 == CrossVal.nil && colorleft == CrossVal.nil)
                return cs.LOWALIVE2;

            //其余在下边返回没有威胁

        }
        return cs.NOTHREAT;//返回没有威胁
    }

    int giveScore(Situation situation)
    {
        int die4 = situation.die4 + situation.lowdie4;
        int alive3 = situation.alive3 + situation.tiao3;
        int alive2 = situation.alive2 + situation.lowalive2;

        if (situation.win5 >= 1)
            return cs.LevelOne;//赢5

        if (situation.alive4 >= 1 || die4 >= 2 || (die4 >= 1 && alive3 >= 1))
            return cs.Leveltwo;//活4 双死4 死4活3

        if (alive3 >= 2)
            return cs.Levelthree;//双活3

        if (situation.die3 >= 1 && situation.alive3 >= 1)
            return cs.Levelfour;//死3高级活3

        if (situation.die4 >= 1)
            return cs.Levelfive;//高级死4

        if (situation.lowdie4 >= 1)
            return cs.Levelsix;//低级死4

        if (situation.alive3 >= 1)
            return cs.Levelseven;//单活3

        if (situation.tiao3 >= 1)
            return cs.LevelEight;//跳活3

        if (alive2 >= 2)
            return cs.LevelNight;//双活2

        if (situation.alive2 >= 1)
            return cs.LevelTen;//活2

        if (situation.lowalive2 >= 1)
            return cs.LevelEleven;//低级活2

        if (situation.die3 >= 1)
            return cs.LevelTwelve;//死3

        if (situation.die2 >= 1)
            return cs.LevelThirteen;//死2

        return cs.LevelFourteen;//没有威胁
    }

    Point maxScore(int[,] myscore, int[,] hisscore)
    {
        Point position = new Point();

        int mymaxscore = 0;//初始化为0
        int hismaxscore = 0;

        List<Point> mypositionvector = new List<Point>();
        List<Point> hispositionvector = new List<Point>();

        for (int i = 0; i < 15; i++)//设置我的最大值向量
            for (int j = 0; j < 15; j++)
            {
                if (myscore[i,j] == mymaxscore)
                {//添加位置向量数据
                    position.x = i;
                    position.y = j;
                    mypositionvector.Add(position);
                }
                if (myscore[i,j] > mymaxscore)
                {//肯定有大于0的分数
                    mymaxscore = myscore[i,j];//替换最大值
                    mypositionvector.Clear();//清除位置向量数据
                                             //添加新位置数据
                    position.x = i;
                    position.y = j;
                    mypositionvector.Add(position);
                }
            }

        for (int i = 0; i < 15; i++)//设置对手的最大值向量
            for (int j = 0; j < 15; j++)
            {
                if (hisscore[i,j] == hismaxscore)
                {
                    position.x = i;
                    position.y = j;
                    hispositionvector.Add(position);
                }
                if (hisscore[i,j] > hismaxscore)
                {//肯定有大于0的分数
                    hismaxscore = hisscore[i,j];//替换最大值
                    hispositionvector.Clear();//清除位置向量数据

                    position.x = i;
                    position.y = j;
                    hispositionvector.Add(position);
                }

            }

        if (mymaxscore >= hismaxscore)
        {//进攻 
            int temp = 0;//存储对手在这些位置中的最大分数
            foreach(var maxtemp in mypositionvector)
            {
                if (hisscore[maxtemp.x, maxtemp.y] >= temp)
                {   //肯定会进来
                    temp = hisscore[maxtemp.x, maxtemp.y];//替换最大值
                    position = maxtemp;//替换位置
                }
            }
            return position;//返回我的最大值中对手也最大的位置
        }
        else
        {//防守
            int temp = 0;//存储自己在这些位置中的最大分数
            foreach (var maxtemp in hispositionvector)
            {
                if (myscore[maxtemp.x, maxtemp.y] >= temp)
                {   //肯定会进来
                    temp = myscore[maxtemp.x, maxtemp.y];//替换最大值
                    position = maxtemp;//替换位置
                }
            }

            return position;//返回对手的最大值中我也最大的位置
        }
    }
}
